makeShrinkageF <- function(version,lambdaVal){
  function(MoGmodel){
    C <- length(MoGmodel$Pc)
    for(c in 1:C){
      T <- computeShrinkageTarget(MoGmodel$Sigma[[c]],version)
      MoGmodel$Sigma[[c]] <- (1-lambdaVal)*MoGmodel$Sigma[[c]] + lambdaVal*T
    }
    return(MoGmodel)
  }
}

doShrinkage <- function(S,T,lambdaVal){
  ## TODO: should I make sure lambdaVal is between zero and one?
  return(lambdaVal*T + (1-lambdaVal)*S)
}

computeShrinkageTarget <- function(S,version="diagUnitVar"){
  if(regexpr("diagUnitVar",version) != -1){
    T <- diag(nrow(S))
  }
  else if(regexpr("diagCmnCov",version) != -1){
    T <- diag(nrow(S)) * mean(diag(S))
  }
  else if(regexpr("cmnCov",version) != -1){
    ## not sure matlab implementation is correct
  }
  else if(regexpr("diagVar",version) != -1){
    T = diag(diag(S))
  }
  else if(regexpr("perfPosCorr",version) != -1){
    stop(version," not implemented yet.")
  }
  else if(regexpr("constCorr",version) != -1){
    stop(version," not implemented yet.")
  }
  else{
    stop(version," not a valid shrinkage target version.")
  }
}

makeLDAcovRegF <- function(X){
  ## X is data by column
  commonSigma <- X %*% t(X)
  function(MoGmodel){
    C <- length(MoGmodel$Pc)
    for(c in 1:C){
      MoGmodel$Sigma[[c]] <- commonSigma
    }
    return(MoGmodel)
  }
}
